home *** CD-ROM | disk | FTP | other *** search
/ Freelog 100 / FreelogNo100-NovembreDecembre2010.iso / Musique / solfege / solfege-win32-3.17.0.exe / {app} / bin / Lib / cProfile.py < prev    next >
Text File  |  2006-02-14  |  6KB  |  191 lines

  1. #! /usr/bin/env python
  2.  
  3. """Python interface for the 'lsprof' profiler.
  4.    Compatible with the 'profile' module.
  5. """
  6.  
  7. __all__ = ["run", "runctx", "help", "Profile"]
  8.  
  9. import _lsprof
  10.  
  11. # ____________________________________________________________
  12. # Simple interface
  13.  
  14. def run(statement, filename=None, sort=-1):
  15.     """Run statement under profiler optionally saving results in filename
  16.  
  17.     This function takes a single argument that can be passed to the
  18.     "exec" statement, and an optional file name.  In all cases this
  19.     routine attempts to "exec" its first argument and gather profiling
  20.     statistics from the execution. If no file name is present, then this
  21.     function automatically prints a simple profiling report, sorted by the
  22.     standard name string (file/line/function-name) that is presented in
  23.     each line.
  24.     """
  25.     prof = Profile()
  26.     result = None
  27.     try:
  28.         try:
  29.             prof = prof.run(statement)
  30.         except SystemExit:
  31.             pass
  32.     finally:
  33.         if filename is not None:
  34.             prof.dump_stats(filename)
  35.         else:
  36.             result = prof.print_stats(sort)
  37.     return result
  38.  
  39. def runctx(statement, globals, locals, filename=None):
  40.     """Run statement under profiler, supplying your own globals and locals,
  41.     optionally saving results in filename.
  42.  
  43.     statement and filename have the same semantics as profile.run
  44.     """
  45.     prof = Profile()
  46.     result = None
  47.     try:
  48.         try:
  49.             prof = prof.runctx(statement, globals, locals)
  50.         except SystemExit:
  51.             pass
  52.     finally:
  53.         if filename is not None:
  54.             prof.dump_stats(filename)
  55.         else:
  56.             result = prof.print_stats()
  57.     return result
  58.  
  59. # Backwards compatibility.
  60. def help():
  61.     print "Documentation for the profile/cProfile modules can be found "
  62.     print "in the Python Library Reference, section 'The Python Profiler'."
  63.  
  64. # ____________________________________________________________
  65.  
  66. class Profile(_lsprof.Profiler):
  67.     """Profile(custom_timer=None, time_unit=None, subcalls=True, builtins=True)
  68.  
  69.     Builds a profiler object using the specified timer function.
  70.     The default timer is a fast built-in one based on real time.
  71.     For custom timer functions returning integers, time_unit can
  72.     be a float specifying a scale (i.e. how long each integer unit
  73.     is, in seconds).
  74.     """
  75.  
  76.     # Most of the functionality is in the base class.
  77.     # This subclass only adds convenient and backward-compatible methods.
  78.  
  79.     def print_stats(self, sort=-1):
  80.         import pstats
  81.         pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
  82.  
  83.     def dump_stats(self, file):
  84.         import marshal
  85.         f = open(file, 'wb')
  86.         self.create_stats()
  87.         marshal.dump(self.stats, f)
  88.         f.close()
  89.  
  90.     def create_stats(self):
  91.         self.disable()
  92.         self.snapshot_stats()
  93.  
  94.     def snapshot_stats(self):
  95.         entries = self.getstats()
  96.         self.stats = {}
  97.         callersdicts = {}
  98.         # call information
  99.         for entry in entries:
  100.             func = label(entry.code)
  101.             nc = entry.callcount         # ncalls column of pstats (before '/')
  102.             cc = nc - entry.reccallcount # ncalls column of pstats (after '/')
  103.             tt = entry.inlinetime        # tottime column of pstats
  104.             ct = entry.totaltime         # cumtime column of pstats
  105.             callers = {}
  106.             callersdicts[id(entry.code)] = callers
  107.             self.stats[func] = cc, nc, tt, ct, callers
  108.         # subcall information
  109.         for entry in entries:
  110.             if entry.calls:
  111.                 func = label(entry.code)
  112.                 for subentry in entry.calls:
  113.                     try:
  114.                         callers = callersdicts[id(subentry.code)]
  115.                     except KeyError:
  116.                         continue
  117.                     nc = subentry.callcount
  118.                     cc = nc - subentry.reccallcount
  119.                     tt = subentry.inlinetime
  120.                     ct = subentry.totaltime
  121.                     if func in callers:
  122.                         prev = callers[func]
  123.                         nc += prev[0]
  124.                         cc += prev[1]
  125.                         tt += prev[2]
  126.                         ct += prev[3]
  127.                     callers[func] = nc, cc, tt, ct
  128.  
  129.     # The following two methods can be called by clients to use
  130.     # a profiler to profile a statement, given as a string.
  131.  
  132.     def run(self, cmd):
  133.         import __main__
  134.         dict = __main__.__dict__
  135.         return self.runctx(cmd, dict, dict)
  136.  
  137.     def runctx(self, cmd, globals, locals):
  138.         self.enable()
  139.         try:
  140.             exec cmd in globals, locals
  141.         finally:
  142.             self.disable()
  143.         return self
  144.  
  145.     # This method is more useful to profile a single function call.
  146.     def runcall(self, func, *args, **kw):
  147.         self.enable()
  148.         try:
  149.             return func(*args, **kw)
  150.         finally:
  151.             self.disable()
  152.  
  153. # ____________________________________________________________
  154.  
  155. def label(code):
  156.     if isinstance(code, str):
  157.         return ('~', 0, code)    # built-in functions ('~' sorts at the end)
  158.     else:
  159.         return (code.co_filename, code.co_firstlineno, code.co_name)
  160.  
  161. # ____________________________________________________________
  162.  
  163. def main():
  164.     import os, sys
  165.     from optparse import OptionParser
  166.     usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
  167.     parser = OptionParser(usage=usage)
  168.     parser.allow_interspersed_args = False
  169.     parser.add_option('-o', '--outfile', dest="outfile",
  170.         help="Save stats to <outfile>", default=None)
  171.     parser.add_option('-s', '--sort', dest="sort",
  172.         help="Sort order when printing to stdout, based on pstats.Stats class", default=-1)
  173.  
  174.     if not sys.argv[1:]:
  175.         parser.print_usage()
  176.         sys.exit(2)
  177.  
  178.     (options, args) = parser.parse_args()
  179.     sys.argv[:] = args
  180.  
  181.     if (len(sys.argv) > 0):
  182.         sys.path.insert(0, os.path.dirname(sys.argv[0]))
  183.         run('execfile(%r)' % (sys.argv[0],), options.outfile, options.sort)
  184.     else:
  185.         parser.print_usage()
  186.     return parser
  187.  
  188. # When invoked as main program, invoke the profiler on a script
  189. if __name__ == '__main__':
  190.     main()
  191.